package com.itheima.aspect;

import com.itheima.mapper.EmpLoginMapper;
import com.itheima.pojo.entity.Emp;
import com.itheima.pojo.entity.LoginInfo;
import com.itheima.pojo.entity.Result;
import com.itheima.pojo.log.EmpLoginLog;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.time.LocalDateTime;

/**
 * @author zzw
 * @date 2025/5/5
 * @description 登录记录切面
 */
@Slf4j
@Aspect
@Component
public class LoginAspect {

    @Autowired
    private EmpLoginMapper empLoginMapper;

    @Pointcut("@annotation(com.itheima.annotation.LoginOperation)")
    public void pointcut() {
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 1. 初始化日志对象
        EmpLoginLog empLoginLog = new EmpLoginLog();

        // 2. 提前提取参数中的用户信息
        try {
            Object[] args = joinPoint.getArgs();
            if (args.length > 0 && args[0] instanceof Emp emp) {
                empLoginLog.setUsername(emp.getUsername());
                empLoginLog.setPassword(emp.getPassword());
            }
        } catch (Exception e) {
            log.warn("提取登录参数失败", e);
        }

        Object result;
        long startTime = System.currentTimeMillis();
        try {
            // 3. 执行目标方法
            result = joinPoint.proceed();

            // 4. 设置登录时间和结果状态
            empLoginLog.setLoginTime(LocalDateTime.now());

            if (result instanceof Result) {
                int code = ((Result) result).getCode();
                empLoginLog.setIsSuccess((short) code);

                if (((Result) result).getData() instanceof LoginInfo loginInfo) {
                    empLoginLog.setJwt(loginInfo.getToken());
                }
            }

        } catch (Throwable e) {
            // 5. 捕获异常，设置失败状态
            empLoginLog.setIsSuccess((short) 0);
            throw e;
        } finally {
            // 6. 统一设置耗时
            long endTime = System.currentTimeMillis();
            empLoginLog.setCostTime(endTime - startTime);

            // 7. 记录日志并持久化
            log.info("登录信息：{}", empLoginLog);
            empLoginMapper.insert(empLoginLog);
        }

        return result;
    }

}
